package com.imooc.es.service.impl;

import com.github.pagehelper.PageHelper;
import com.imooc.es.service.ItemSearchService;
import com.imooc.es.mapper.SearchMapperCustom;
import com.imooc.es.pojo.vo.Items;
import com.imooc.es.pojo.vo.SearchItemsVO;
import com.imooc.pojo.PagedGridResult;
import com.imooc.service.BaseService;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 顾志杰
 * @date 2020/9/7-14:39
 */
@RestController
public class SearchServiceImpl extends BaseService implements ItemSearchService {

    private final SearchMapperCustom searchItemsByThirdCat;

    private final ElasticsearchTemplate esTemplate;

    @Autowired
    public SearchServiceImpl(SearchMapperCustom searchItemsByThirdCat, ElasticsearchTemplate esTemplate) {
        this.searchItemsByThirdCat = searchItemsByThirdCat;
        this.esTemplate = esTemplate;
    }

    @Override
    public PagedGridResult seathItems(String keywords, String sort, Integer page, Integer pageSize) {
        Pageable pageable = PageRequest.of(page, pageSize);
        SortBuilder sortBuilder = null;
        if("c".equals(sort)){
            sortBuilder = new FieldSortBuilder("sellCounts").order(SortOrder.DESC);
        }else if ("p".equals(sort)){
            sortBuilder = new FieldSortBuilder("price").order(SortOrder.ASC);
        }else{
            /*如果字段是类型是text需要用它的keyword来进行排序*/
            sortBuilder = new FieldSortBuilder("itemName.keyword").order(SortOrder.ASC);
        }
        String preTag = "<font color = 'red'>";
        String postTag = "</font>";
        String itemNameFiled = "itemName";
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchQuery(itemNameFiled, keywords))
                .withHighlightFields(new HighlightBuilder.Field(itemNameFiled)
//                        .preTags(preTag)
//                        .postTags(postTag)
                )
                .withSort(sortBuilder)
                .withPageable(pageable)
                .build();
        AggregatedPage<Items> items = esTemplate.queryForPage(searchQuery, Items.class, new SearchResultMapper() {
            @Override
            public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
                List<Items> itemsList = new ArrayList<>();
                SearchHits hits = response.getHits();
                hits.forEach(h -> {
                    HighlightField description = h.getHighlightFields().get(itemNameFiled);
                    String s = description.getFragments()[0].toString();
                    Items items = new Items();
                    items.setItemId((String) h.getSourceAsMap().get("itemId"));
                    items.setImgUrl((String) h.getSourceAsMap().get("imgUrl"));
                    items.setPrice((Integer) h.getSourceAsMap().get("price"));
                    items.setSellCounts((Integer) h.getSourceAsMap().get("sellCounts"));
                    items.setItemName(s);
                    itemsList.add(items);
                });
                return new AggregatedPageImpl<>((List<T>) itemsList,pageable,response.getHits().getTotalHits());
            }
        });
//
//        PagedGridResult pagedGridResult = new PagedGridResult();
//        pagedGridResult.setRows(items.getContent());
//        pagedGridResult.setPage(page + 1);
//        pagedGridResult.setTotal(items.getTotalPages());
//        pagedGridResult.setRecords(items.getTotalElements());

        return setterPagedGrid(items.getContent(), page+1);
    }

    @Transactional(propagation = Propagation.SUPPORTS, rollbackFor = Exception.class)
    @Override
    public PagedGridResult seathItems(Integer catId, String sort, Integer page, Integer pageSize) {
        Map<String,Object> map = new HashMap<>();
        map.put("catId", catId);
        map.put("sort", sort);
        PageHelper.startPage(page, pageSize);
        List<SearchItemsVO> searchItems = searchItemsByThirdCat.searchItemsByThirdCat(map);
        return setterPagedGrid(searchItems, page);
    }
}
